package com.jsmile.cloud.taskcenter.task.repo;

import java.util.Collections;
import java.util.List;

import javax.annotation.PostConstruct;

import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jsmile.cloud.taskcenter.api.exception.TaskException;
import com.jsmile.cloud.taskcenter.api.req.ReqTaskDelete;
import com.jsmile.cloud.taskcenter.api.req.ReqTaskQuery;
import com.jsmile.cloud.taskcenter.task.dao.TaskDao;
import com.jsmile.cloud.taskcenter.task.kit.TaskKit;
import com.jsmile.cloud.taskcenter.task.model.TaskModel;
import com.jsmile.mall.api.enums.SfEnum;

import lombok.extern.slf4j.Slf4j;

/**
 * @author 龚亮
 * @version 1.0
 * @desc 为了薪资破万，还是睡一会儿吧...!
 * @date 2020年06月04日 04:39:24
 */
@Service
@Slf4j
@Transactional(readOnly = false, rollbackFor = Exception.class)
public class TaskRepository extends ServiceImpl<TaskDao, TaskModel> {

    /**
     * D:初始化任务
     */
    @PostConstruct
    public void init() throws Exception {
        List<TaskModel> jobList = this.list(getQueryWrapper(ReqTaskQuery.builder().taskStatus(SfEnum.S.getValue()).build()));
        List<TaskModel> existsJobList = TaskKit.getAllJob();
        /*
         * 删除当前系统不存在的任务
         */
        for (TaskModel task : existsJobList) {
            int i = Collections.frequency(jobList, task);
            if (i < 1) {
                log.error("当前任务数量:" + existsJobList.size() + ",当前任务:【" + task.getJobName() + "】不存在!");
                TaskKit.deleteJob(task);
            }
        }
        /*
         * 恢复或启动任务
         */
        for (TaskModel task : jobList) {
            if (SfEnum.S.getValue() == task.getTaskStatus()) {
                TaskKit.existsJobUpdateCron(task);
            } else {
                TaskKit.pauseJob(task);
            }
        }

    }

    public boolean saveTask(TaskModel task) throws SchedulerException {
        task.setBeanClass(task.getBeanClass().trim());
        if (this.save(task)) {
            TaskKit.addJob(task, null);
        } else {
            throw new TaskException("创建定时任务失败!");
        }
        return Boolean.TRUE;
    }

    public boolean pauseJob(TaskModel task) throws SchedulerException {
        if (this.updateById(task)) {
            TaskKit.pauseJob(task);
        } else {
            throw new TaskException("暂停定时任务失败!");
        }
        return Boolean.TRUE;
    }

    public boolean resumeJob(TaskModel task) throws SchedulerException {
        if (this.updateById(task)) {
            TaskKit.resumeJob(task);
        } else {
            throw new TaskException("暂停定时任务失败!");
        }
        return Boolean.TRUE;
    }

    public boolean runJob(TaskModel task) {
        try {
            TaskKit.runAJobNow(task);
        } catch (SchedulerException e) {
            throw new TaskException("启动定时任务失败!");
        }
        return Boolean.TRUE;
    }

    public boolean deleteTasks(ReqTaskDelete reqTaskDelete) {
        List<TaskModel> tasks = this.baseMapper.selectBatchIds(reqTaskDelete.getIds());
        tasks.forEach(task -> {
            try {
                TaskKit.deleteJob(task);
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        });
        this.removeByIds(reqTaskDelete.getIds());
        return Boolean.TRUE;
    }

    public IPage<TaskModel> page(ReqTaskQuery reqTaskQuery) {
        return this.page(reqTaskQuery.getPage(), getQueryWrapper(reqTaskQuery));
    }

    public List<TaskModel> list(ReqTaskQuery reqTaskQuery) {
        return this.list(getQueryWrapper(reqTaskQuery));
    }

    private Wrapper getQueryWrapper(ReqTaskQuery reqTaskQuery) {
        return new QueryWrapper<TaskModel>().lambda().eq(null != reqTaskQuery.getTaskType(), TaskModel::getTaskType, reqTaskQuery.getTaskType())
            .eq(null != reqTaskQuery.getTaskStatus(), TaskModel::getTaskStatus, reqTaskQuery.getTaskStatus()).orderByDesc(TaskModel::getCreateTime);
    }
}
